<?php
/**
 * 系统告知静态类
 * 
 * 包含：
 * 	1、系统消息
 * 	2、好友申请
 *
 * @author will
 * @version $Id$
 */

class SysMsg
{
	static public $TYPE_SYSTEM = 1;			// 系统消息
	static public $TYPE_FRIEND = 2;			// 好友申请
	static public $ALL_TYPES = array(1 , 2);		// 所有类型
	
	/**
	 * 获取消息的总数
	 * @param <int> $uin
	 * @param <int> $type
	 */
	static public function getTotalNum($uin , $get_type = 0) {
		return self::getNum($uin , $get_type , 'total');
	}
	
	/**
	 * 获取消息未读数
	 * @param <int> $uin
	 * @param <int> $type
	 */
	static public function getUnreadNum($uin , $get_type = 0) {
		return self::getNum($uin , $get_type , 'new');
	}
	
	/**
	 * 设置已读
	 * @param <int> $uin
	 * @param <int> $type
	 * @param <int | array> $ids
	 */
	static public function setRead($uin , $type , $ids) {
		if(empty($ids)) return array();
		
		$Db = loadDB();
		if(is_array($ids)) {
			$ids = array_unique($ids);
			$ids_str = implode(',' , $ids);
			$success = $Db->query("UPDATE `sysmsg` SET `isread` = 1 WHERE `uin` = {$uin} AND `type` = {$type} AND `id` IN ({$ids_str})");
		} else {
			$success = $Db->query("UPDATE `sysmsg` SET `isread` = 1 WHERE `uin` = {$uin} AND `type` = {$type} AND `id` = ({$uins})");
		}
		
		// 清空数字
		self::deleteNum($uin , $type);
		
		return $success ? 0 : -1;
	}
	
	static public function deleteNum($uin , $type) {
		$Db = loadDB();
		
		$query = "DELETE FROM `sysmsg_num` WHERE `uin` = {$uin}";
		if(!empty($type)) {
			$query .= " AND `type` = {$type}";
		}
		$success = $Db->query($query);
		
		return $success ? 0 : -1;
	}
	
	/**
	 * 获取消息未读数 | 总数
	 * @param <int> $uin
	 * @param <int> $get_type
	 * @param <string> $num_type
	 */
	static public function getNum($uin , $get_type , $num_type) {
		$Db = loadDB();
		
		// 先查数字表中的情况
		$query = "SELECT `type` , `{$num_type}` FROM `sysmsg_num` WHERE `uin` = {$uin}";
		if($get_type > 0) {
			$query .= " AND `type` = {$get_type}";
		}
		
		$result = $Db->getAll($query);
		$count_result = array();
		foreach($result as $row) {
			$count_result[$row['type']] = $row[$num_type];
		}
		
		// 判断数据是否足够，不够的话，需要重新计算
		$need_refresh = false;
		$search_types = $get_type > 0 ? array($get_type) : self::$ALL_TYPES;
		foreach($search_types as $type) {
			if(!isset($count_result[$type])) {
				$need_refresh = true;
				break;
			}
		}
		
		$return_data = array();
		foreach($search_types as $type) {
			$return_data[$type] = isset($count_result[$type]) ? $count_result[$type] : 0;
		}
		
		// 如果要刷新的话
		if($need_refresh) {
			$refresh_result = self::refreshNum($uin , $get_type);
			$return_data = $num_type == 'new' ? $refresh_result['unread'] : $refresh_result['total'];
		}
		
		return $get_type > 0 ? $return_data[$get_type] : $return_data;
	}
	
	/**
	 * 刷新计数
	 * @param <int> $uin
	 * @param <int> $get_type
	 */
	static public function refreshNum($uin , $get_type) {
		$Db = loadDB();
		
		$search_types = $get_type > 0 ? array($get_type) : self::$ALL_TYPES;
		
		$query = "SELECT `type` , `isread` FROM `sysmsg` WHERE `uin` = {$uin}";
		if($get_type > 0) {
			$query .= " AND `type` = {$get_type}";
		}
		$result = $Db->getAll($query);
		
		$data_result = array();
		
		// 初始化数组
		$unread_num_data = array();
		$total_num_data = array();
		foreach($search_types as $type) {
			$unread_num_data[$type] = 0;
			$total_num_data[$type] = 0;
		}
		
		foreach($result as $row) {
			if($row['isread'] == 0) {
				$unread_num_data[$row['type']]++;
			}
			$total_num_data[$row['type']]++;
		}
		
		// 刷新 num 表
		self::deleteNum($uin , $get_type);
		
		$insert_array = array();
		$time = time();
		foreach($unread_num_data as $type => $num) {
			$new = $num;
			$total = $total_num_data[$type];
			array_push($insert_array , "({$uin} , {$type} , {$new} , {$total} , {$time})");
		}
		
		$query = "INSERT INTO `sysmsg_num` (`uin` , `type` , `new` , `total` , `time`) VALUES " . implode(',' , $insert_array);
		$Db->query($query);
		
		return array('unread' => $unread_num_data , 'total' => $total_num_data);
	}
	
	/**
	 * 获取消息列表数据
	 * @param <int> $uin
	 * @param <int> $type
	 * @param <int> $offset 偏移量
	 * @param <int> $limit 要取的数据条数
	 */
	static public function getList($uin , $type , $offset = 0 , $limit = 10) {
		$Db = loadDB();
		$query = "SELECT * FROM `sysmsg` WHERE `uin` = {$uin} AND `type` = {$type} ORDER BY `time` DESC LIMIT {$offset} , {$limit}";
		$result = $Db->getAll($query);
		
		foreach($result as $k => $row) {
			if(!empty($row['data'])) {
				$result[$k]['data'] = unserialize($row['data']);
			}
		}
		//print_r($result);
		return $result;
	}
	
	/**
	 * 获取一条消息列表数据
	 * @param <int> $uin
	 * @param <int> $type
	 * @param <int> $id
	 */
	static public function getOne($uin , $type , $id) {
		$Db = loadDB();
		$query = "SELECT * FROM `sysmsg` WHERE `uin` = {$uin} AND `type` = {$type} AND `id` = {$id}";
		$result = $Db->getOne($query);
		
		return $result;
	}
	
	/**
	 * 发送消息
	 * 注：这个非对外接口，尽量不要使用，发送不同类型，用对应的接口
	 * @param <int> $uin
	 * @param <int> $type
	 * @param <int> $id
	 * @param <int> $subtype
	 * @param <array> $data
	 * 
	 * @return <int>
	 */
	static public function send($uin , $type , $id , $subtype = 1 , $data = null) {
		$Db = loadDB();
		
		$data = !empty($data) ? serialize($data) : '';
		$data = Db::filter($data);
		$time = time();
		
		// 写入或更新
		$query = "INSERT INTO `sysmsg` 
							(`uin` , `type` , `id` , `subtype` , `data` , `time` , `isread`) 
							VALUES 
							({$uin} , {$type} , {$id} , {$subtype} , '{$data}' , {$time} , 0) 
								ON DUPLICATE KEY UPDATE `subtype` = {$subtype} , `data` = '{$data}' , `time` = {$time} , `isread` = 0";
		$success = $Db->query($query);
		
		// 有更新后，需要同步更新系统告知数字(目前做法是删除数字，获取时重新计算)
		self::deleteNum($uin , $type);
		
		return $success ? 0 : -1;
	}
	
	/**
	 * 发送系统消息
	 * @param <int> $uin
	 * @param <array> $data
	 * @param <int> $subtype
	 */
	static public function sendSystem($uin , $data , $subtype = 0) {
		$id = isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : time();
		return self::send($uin , self::$TYPE_SYSTEM , $id , $subtype , $data);
	}
	
	/**
	 * 发送好友申请
	 * @param <int> $uin
	 * @param <int> $send_uin
	 */
	static public function sendFriend($uin , $send_uin) {
		return self::send($uin , self::$TYPE_FRIEND , $send_uin , 1 , array('send_uin' => $send_uin));
	}
	
/**
	 * 删除消息
	 * @param <int> $uin
	 * @param <int> $type
	 * @param <int> $id
	 */
	static public function delete($uin , $type , $id) {
		$Db = loadDB();
		
		$query = "DELETE FROM `sysmsg` WHERE `uin` = {$uin}";
		if(!empty($type)) {
			$query .= " AND `type` = {$type}";
			
			if(!empty($id)) {
				$query .= " AND `id` = {$id}";
			}
		}
		
		$success = $Db->query($query);
		
		// 有更新后，需要同步更新系统告知数字(目前做法是删除数字，获取时重新计算)
		self::deleteNum($uin , $type);
		
		return $success ? 0 : -1;
	}
}

#end of script
